package com.yisu.auction.manager.website.controller.dataAnalysis;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.yisu.auction.ewf.common.web.JsonResult;
import com.yisu.auction.ewf.entity.GoodsInfo;
import com.yisu.auction.ewf.entity.Show;
import com.yisu.auction.manager.core.service.IDataAnalysisService;
import com.yisu.auction.manager.core.service.IGoodsInfoService;
import com.yisu.auction.manager.core.service.IShowService;
import com.yisu.auction.manager.domain.util.CacheManager;
import com.yisu.auction.manager.domain.util.ImageMarkLogoByIcon;
import com.yisu.auction.manager.domain.util.UnCompressFile;
import com.yisu.auction.manager.domain.vo.Cache;
import com.yisu.auction.manager.domain.vo.dataAnalysis.AnalysisGoodsVo;
import com.yisu.auction.manager.domain.vo.dataAnalysis.AnalysisImageVo;
import com.yisu.auction.manager.domain.vo.dataAnalysis.EvaluateVo;
import com.yisu.auction.manager.website.controller.BaseController;
import org.apache.calcite.linq4j.Linq4j;
import org.apache.calcite.linq4j.function.Function1;
import org.apache.calcite.linq4j.function.Predicate1;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;

import static com.yisu.auction.ewf.common.enums.ResponseCode.FAILURE;
import static com.yisu.auction.ewf.common.enums.ResponseCode.SUCCESS;

/**
 * author: 赵杰
 * Business Description：数据解析
 * createTime：2017/9/6
 */
@Controller
@RequestMapping(value = "/dataAnalysis")
public class DataAnalysisController extends BaseController {
    private String thisPath = "";
    private static List<AnalysisGoodsVo> analysisGoodsVos = Lists.newArrayList();
    private List<AnalysisImageVo> goodsMainImages;
    private List<AnalysisImageVo> goodsDetailmages;
    private List<AnalysisImageVo> evaluateImages;
    private List<EvaluateVo> evaluateVos;

    @Resource
    private IDataAnalysisService iDataAnalysisService;
    @Resource
    private IGoodsInfoService iGoodsInfoService;
    @Resource
    private IShowService iShowService;


    @RequestMapping(value = "/index.htm")
    public String index(Model model, HttpServletRequest request) throws Exception {
        thisPath = request.getSession().getServletContext().getRealPath("") + File.separator + "fileUpload" + File.separator;
        Cache cache = CacheManager.getCacheInfo("analysisGoodsVos");
        if (cache != null) {
            analysisGoodsVos = JSON.parseArray(String.valueOf(cache.getValue()), AnalysisGoodsVo.class);
        } else {
            analysisGoodsVos = Lists.newArrayList();
        }
        model.addAttribute("analysisGoodsVos", analysisGoodsVos);
        return "/dataAnalysis/index";
    }


    /**
     * 校验商品数据
     *
     * @param model 页面传参
     * @return 页面
     */
    @RequestMapping(value = "/checkGoodsAnalysis.json")
    @ResponseBody
    public JsonResult checkGoodsAnalysis(Model model, HttpServletRequest request) {
        AnalysisGoodsVo errorModel = new AnalysisGoodsVo();
        try {
            if (CollectionUtils.isEmpty(analysisGoodsVos)) {
                return new JsonResult(FAILURE.code, "未检测到任何可执行性数据...");
            }
            List<AnalysisGoodsVo> convertModels = Lists.newArrayList();

            for (final AnalysisGoodsVo goodsItem : analysisGoodsVos) {
                errorModel = goodsItem;
                //检测图片
                goodsMainImages = Lists.newArrayList();
                goodsDetailmages = Lists.newArrayList();
                String iamgePath = thisPath + "图片" + File.separator;
                getFileList(iamgePath, goodsItem.getSalesNo(), 1);
                getFileList(iamgePath, goodsItem.getSalesNo(), 2);
                if (CollectionUtils.isEmpty(goodsMainImages)) {
                    return new JsonResult(FAILURE.code, "编号：" + goodsItem.getSalesNo() + ",商品：" + goodsItem.getGoodsName() + "未检测到主图片信息");
                }
                goodsItem.setGoodsMainImages(goodsMainImages);
                goodsItem.setGoodsDetailmages(goodsDetailmages);
             /*   goodsItem.setMainPic(getImageUrl(goodsMainImages));
                goodsItem.setDetailPic(getImageUrl(goodsMainImages));*/
                convertModels.add(goodsItem);
                CacheManager.clearOnly("analysisGoodsVos");
                CacheManager.putCache("analysisGoodsVos", new Cache("analysisGoodsVos", JSON.toJSONString(analysisGoodsVos), 50, false));
            }
            analysisGoodsVos = convertModels;

            return new JsonResult(SUCCESS.code, "数据校验成功...");
        } catch (Exception e) {
            logger.error("校验商品数据异常：" + e.getMessage() + "json:" + JSON.toJSONString(errorModel));
            return new JsonResult(FAILURE.code, ("校验商品数据异常：" + e.getMessage() + "json:" + JSON.toJSONString(errorModel)));
        }
    }


    /**
     * 校验商品数据
     *
     * @param model 页面传参
     * @return 页面
     */
    @RequestMapping(value = "/goodsAnalysis.json")
    @ResponseBody
    public JsonResult goodsAnalysis(Model model, HttpServletRequest request) {
        if (CollectionUtils.isEmpty(analysisGoodsVos)) {
            return new JsonResult(FAILURE.code, "未检测到任何可执行性数据...");
        }
        if (iDataAnalysisService.addGoodsInfo(analysisGoodsVos)) {
            return new JsonResult(FAILURE.code, "数据执行成功");
        }
        return new JsonResult(FAILURE.code, "数据执行失败");
    }

    /**
     * 加载商品数据
     *
     * @param model 页面传参
     * @return 页面
     */
    @RequestMapping(value = "/loadDataForGoods.json")
    @ResponseBody
    public JsonResult loadDataForGoods(Model model, HttpServletRequest request) {
        try {
            if (loadDataForGoodsAction()) {
                return new JsonResult(SUCCESS.code, "加载商品数据成功...");
            }
        } catch (Exception e) {
            logger.error("加载商品数据异常：" + e.getMessage());
        }
        return new JsonResult(FAILURE.code, "网络君泡妞去了...");
    }


    /**
     * 加载商品数据
     *
     * @param model 页面传参
     * @return 页面
     */
    @RequestMapping(value = "/updatePrice.json")
    @ResponseBody
    public JsonResult updatePrice(Model model, HttpServletRequest request) {
        try {
            if (CollectionUtils.isEmpty(analysisGoodsVos)) {
                return new JsonResult(FAILURE.code, "未检测到任何可执行性数据...");
            }
            List<GoodsInfo> goodsInfos = iGoodsInfoService.getGoodsForAll();
            if (!CollectionUtils.isEmpty(goodsInfos)) {
                for (final GoodsInfo item : goodsInfos) {
                    AnalysisGoodsVo thisModel = Linq4j.asEnumerable(analysisGoodsVos).where(new Predicate1<AnalysisGoodsVo>() {
                        @Override
                        public boolean apply(AnalysisGoodsVo analysisGoodsVo) {
                            return analysisGoodsVo.getSalesNo().equals(item.getSalesNo());
                        }
                    }).firstOrDefault();
                    if (thisModel != null) {
                        GoodsInfo updateModel = new GoodsInfo();
                        updateModel.setId(item.getId());
                        updateModel.setPrice(new BigDecimal(thisModel.getPrice()));
                        updateModel.setWaterLevel(new BigDecimal(thisModel.getWaterLevel()));
                        iGoodsInfoService.updateGoodsInfo(updateModel);
                    }
                }
                return new JsonResult(SUCCESS.code, "操作成功!");
            }
        } catch (Exception e) {
            logger.error("加载商品数据异常：" + e.getMessage());
        }
        return new JsonResult(FAILURE.code, "网络君泡妞去了...");
    }


    /**
     * 每日评价初始
     *
     * @return
     */
    @RequestMapping(value = "/evaluateForEvery.json")
    @ResponseBody
    public JsonResult evaluateForEvery() {
        try {
            /**
             * 逻辑，优先获取评价表所有内容；
             * 找出每条评价对应商品的近期开奖期号及时间
             * 将评价时间及期号刷成最新
             */
            if(iShowService.evaluateForEveryDay())
            {
                return new JsonResult(SUCCESS.code, "每日评价初始成功");
            }
          /*  List<Show> showList = iShowService.getShowForAll();
            if (!CollectionUtils.isEmpty(showList)) {
                for (Show item : showList) {
                    if (!StringUtils.isEmpty(item.getImages())) {
                        List<String> imageArray = Linq4j.asEnumerable(item.getImages().split(",")).toList();
                        if (!CollectionUtils.isEmpty(imageArray)) {
                            for (String imageStr : imageArray) {
                                File tempFile = new File(imageStr.trim());
                                iShowService.deleteShowImageByFileName(tempFile.getName());
                            }
                        }
                    }
                }
            }*/
        } catch (Exception e) {
            logger.error("每日评价初始异常：" + e.getMessage());
        }
        return new JsonResult();
    }


    /**
     * 初始晒单信息操作
     *
     * @param model 页面传参
     * @return 页面
     */
    @RequestMapping(value = "/initEvaluate.json")
    @ResponseBody
    public JsonResult initEvaluate(Model model, HttpServletRequest request) {
        List<Show> addShowList = Lists.newArrayList();
        try {
            if (CollectionUtils.isEmpty(analysisGoodsVos)) {
                return new JsonResult(FAILURE.code, "未检测到任何可执行性数据...");
            }
            for (AnalysisGoodsVo itemModel : analysisGoodsVos) {
                evaluateVos = Lists.newArrayList();
                //读取评价图片
                evaluateImages = Lists.newArrayList();
                String imagePath = thisPath + "图片" + File.separator;
                getFileList(imagePath, itemModel.getSalesNo(), 3);
                //读取此商品评价内容
                try {
                    String evaluateExcelPath = thisPath + "竞拍晒单" + File.separator + itemModel.getSalesNo() + File.separator + "评价.xls";
                    AnalysisevaluateExcel(evaluateExcelPath);
                } catch (Exception e) {
                    logger.error("读取图片地址不存在");
                }
                if (evaluateVos.size() > 0) {
                    for (final EvaluateVo evaluateVoItem : evaluateVos) {
                        List<String> imagesArray = Lists.newArrayList();
                        //获取当前商品的，当前评价的图片信息
                        List<AnalysisImageVo> thisImages = Linq4j.asEnumerable(evaluateImages).where(new Predicate1<AnalysisImageVo>() {
                            @Override
                            public boolean apply(AnalysisImageVo analysisImageVo) {
                                String firstStr = analysisImageVo.getName().split("-")[0];
                                if (firstStr.contains(String.valueOf(evaluateVoItem.getSort()))) {
                                    return true;
                                } else {
                                    return false;
                                }
                            }
                        }).toList();
                        if (thisImages != null && thisImages.size() > 0) {
                            //按照名称进行排序
                            thisImages = Linq4j.asEnumerable(thisImages).orderBy(new Function1<AnalysisImageVo, Comparable>() {
                                @Override
                                public Comparable apply(AnalysisImageVo analysisImageVo) {
                                    return analysisImageVo.getName();
                                }
                            }).toList();
                            //排序后的图片进行水印添加
                            for (AnalysisImageVo imageVo : thisImages) {
                                String srcImgPath = imageVo.getImagePath();
                                String iconPath = "D:\\竞拍-水印.png";
                                String targerPath = imageVo.getImagePath();
                                // 给图片添加水印--暂不启动
                                ImageMarkLogoByIcon.markImageByIcon(iconPath, srcImgPath, targerPath, 30);
                                imagesArray.add(srcImgPath);
                            }
                            evaluateVoItem.setImages(imagesArray);
                        }
                    }
                    //开始执行评价数据操作
                    List<GoodsInfo> products = iGoodsInfoService.getGoodsInfoByGoodsName(itemModel.getGoodsName());
                    if (products.size() <= 0) {
                        return new JsonResult(FAILURE.code, "编号：" + itemModel.getSalesNo() + ",商品：" + itemModel.getGoodsName() + "不存在，请检查数据");
                    }
                    if (products.size() > 1) {
                        return new JsonResult(FAILURE.code, "编号：" + itemModel.getSalesNo() + ",商品：" + itemModel.getGoodsName() + "查到了：" + products.size() + ",系统无法识别唯一！");
                    }
                    GoodsInfo product = products.get(0);
                    if (evaluateVos != null && evaluateVos.size() > 0) {
                        for (EvaluateVo addModel : evaluateVos) {
                            if (org.apache.commons.lang3.StringUtils.isEmpty(addModel.getEvaluateContent()))
                                continue;
                            Show show = new Show();
                            show.setStatus(1);
                            show.setCreateDate(new Date());
                            show.setDescrib("");
                            if (!StringUtils.isEmpty(addModel.getEvaluateContent())) {
                                show.setDescrib(addModel.getEvaluateContent().replace("1.", "").replace("2.", "").replace("3.", ""));
                            }
                            show.setIsValid(true);
                            show.setTitle(product.getName());
                            show.setProductId(product.getId());
                            show.setImages(StringUtils.join(addModel.getImages(), ","));
                            addShowList.add(show);
                        }
                    }
                }
            }
            if (!CollectionUtils.isEmpty(addShowList)) {
                if (iShowService.batchAddShow(addShowList)) {
                    return new JsonResult("一键晒单评价成功");
                } else {
                    return new JsonResult(FAILURE.code, "操作失败！");
                }
            }
        } catch (Exception e) {
            return new JsonResult(FAILURE.code, "执行评价操作异常：" + e.getMessage());
        }
        return new JsonResult("一键晒单评价成功");
    }


    //解析excel 商家信息 dataType:1 商品档案 dataType :2 商品评价相关
    public void AnalysisevaluateExcel(String excelPath) {
        try {
            InputStream is = null;
            Workbook wb = null;
            if (!StringUtils.isEmpty(excelPath)) {
                String filePath = excelPath;
                boolean isE2007 = false;    //判断是否是excel2007格式
                if (filePath.endsWith("xlsx"))
                    isE2007 = true;
                is = new FileInputStream(filePath);
                POIFSFileSystem poifsFileSystem = new POIFSFileSystem(is);
                wb = new HSSFWorkbook(poifsFileSystem);
                List<List<Map<String, String>>> result = new ArrayList<List<Map<String, String>>>();//对应excel文件
                int sheetSize = wb.getNumberOfSheets();
                Sheet sheet = wb.getSheetAt(0);
                List<Map<String, String>> sheetList = new ArrayList<Map<String, String>>();//对应sheet页
                List<String> titles = new ArrayList<String>();//放置所有的标题
                int rowSize = sheet.getLastRowNum() + 1;
                int rowNum = 1;
                for (int j = 0; j < rowSize; j++) {//遍历行
                    EvaluateVo evaluateVo = new EvaluateVo();
                    AnalysisGoodsVo analysisGoodsVo = new AnalysisGoodsVo();
                    Row row = sheet.getRow(j);
                    if (row == null) {//略过空行
                        continue;
                    }
                    int cellSize = row.getLastCellNum();//行中有多少个单元格，也就是有多少列
                    if (j == 0) {//第一行是标题行
                        for (int k = 0; k < cellSize; k++) {
                            Cell cell = row.getCell(k);
                            titles.add(cell.toString());
                        }
                    } else {
                        for (int k = 0; k < titles.size(); k++) {
                            Cell cell = row.getCell(k);
                            String key = titles.get(k).trim(); //标题
                            String value = null;
                            if (cell != null) {
                                value = cell.toString(); //对应值
                            }
                            if (key.contains("评价"))
                                key = "评价";
                            switch (key) {
                                case "评价":
                                    evaluateVo.setEvaluateContent(value);
                                    evaluateVo.setSort(rowNum);
                                    break;
                            }
                        }
                    }
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(evaluateVo.getEvaluateContent())) {
                        evaluateVos.add(evaluateVo);
                        rowNum++;
                    }
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 加载商品解析
     *
     * @return
     */
    protected boolean loadDataForGoodsAction() {
        try {
            analysisGoodsVos = Lists.newArrayList();
            //优先执行商品图片解压
            String unzipPath = thisPath + "产品.zip";
            //解压路径
            String decompressionPath = thisPath;
            UnCompressFile.unzip(unzipPath, decompressionPath);
            //加载商品列表信息，读取excel信息
            String excelPath = thisPath + "产品列表.xls";
            AnalysisExcel(excelPath);
            CacheManager.clearOnly("analysisGoodsVos");
            CacheManager.putCache("analysisGoodsVos", new Cache("analysisGoodsVos", JSON.toJSONString(analysisGoodsVos), 50, false));
        } catch (Exception e) {
            logger.error("加载商品档案执行异常：" + e.getMessage());
            return false;
        }
        return true;
    }


    //解析excel 商家信息 dataType:1 商品档案 dataType :2 商品评价相关
    public void AnalysisExcel(String excelPath) {

        try {
            InputStream is = null;
            Workbook wb = null;
            if (!StringUtils.isEmpty(excelPath)) {
                String filePath = excelPath;
                boolean isE2007 = false;    //判断是否是excel2007格式
                if (filePath.endsWith("xlsx"))
                    isE2007 = true;
                is = new FileInputStream(filePath);
                POIFSFileSystem poifsFileSystem = new POIFSFileSystem(is);

                wb = new HSSFWorkbook(poifsFileSystem);

                List<List<Map<String, String>>> result = new ArrayList<List<Map<String, String>>>();//对应excel文件
                int sheetSize = wb.getNumberOfSheets();
                Sheet sheet = wb.getSheetAt(0);
                List<Map<String, String>> sheetList = new ArrayList<Map<String, String>>();//对应sheet页
                List<String> titles = new ArrayList<String>();//放置所有的标题
                int rowSize = sheet.getLastRowNum() + 1;
                int rowNum = 1;
                for (int j = 0; j < rowSize; j++) {//遍历行
                    AnalysisGoodsVo analysisGoodsVo = new AnalysisGoodsVo();
                    Row row = sheet.getRow(j);
                    if (row == null) {//略过空行
                        continue;
                    }
                    int cellSize = row.getLastCellNum();//行中有多少个单元格，也就是有多少列
                    if (j == 0) {//第一行是标题行
                        for (int k = 0; k < cellSize; k++) {
                            Cell cell = row.getCell(k);
                            titles.add(cell.toString());
                        }
                    } else {
                        for (int k = 0; k < titles.size(); k++) {
                            Cell cell = row.getCell(k);
                            String key = titles.get(k).trim(); //标题
                            String value = null;
                            if (cell != null) {
                                value = cell.toString(); //对应值
                            }
                            switch (key) {
                                case "编码":
                                    analysisGoodsVo.setSalesNo(value);
                                    break;
                                case "类目":
                                    analysisGoodsVo.setCategoryName(value);
                                    break;
                                case "描述":
                                    analysisGoodsVo.setCategoryDesc(value);
                                    break;
                                case "商品名称":
                                    analysisGoodsVo.setGoodsName(value);
                                    break;
                                case "商品价格":
                                    analysisGoodsVo.setPrice(value);
                                    break;
                                case "商品水位":
                                    analysisGoodsVo.setWaterLevel(value);
                                    break;
                                case "是否充值卡":
                                    analysisGoodsVo.setIsRechargeCard(value);
                                    break;
                                case "状态":
                                    analysisGoodsVo.setStatus(value);
                                    break;
                                case "是否十元专区":
                                    analysisGoodsVo.setIsTen(value);
                                    break;
                            }

                        }
                    }
                    if (!StringUtils.isEmpty(analysisGoodsVo.getSalesNo())) {
                        analysisGoodsVos.add(analysisGoodsVo);
                    }
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 重置所有数据解析目录；
     *
     * @param model 页面传参
     * @return 页面
     */
    @RequestMapping(value = "/resetDisk.json")
    @ResponseBody
    public JsonResult resetDisk(Model model, HttpServletRequest request) {
        try {
            deleteDir(new File(thisPath));
            return new JsonResult();
        } catch (Exception ex) {
            return new JsonResult(FAILURE.code, "重置所有数据解析目录异常");
        }
    }

    private static boolean deleteDir(File dir) {
        try {
            if (dir.isDirectory()) {
                String[] children = dir.list();//递归删除目录中的子目录下
                for (int i = 0; i < children.length; i++) {
                    boolean success = deleteDir(new File(dir, children[i]));
                    if (!success) {
                        return false;
                    }
                }
            }
        } catch (Exception ex) {
            int i = 0;
        }
        System.gc();
        // 目录此时为空，可以删除
        return dir.delete();
    }


    public void getFileList(String strPath, String dirName, Integer type) {
        File dir = new File(strPath);
        File[] files = dir.listFiles(); // 该文件目录下文件全部放入数组
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                String fileName = files[i].getName();
                if (files[i].isDirectory()) { // 判断是文件还是文件夹
                    if (fileName.contains(dirName)) {
                        String analysisImagePath = "";
                        if (type == 1) {
                            analysisImagePath = files[i].getAbsolutePath() + File.separator + "主图";
                            goodsMainImages = getFileList_ImageItems(analysisImagePath, type);
                        } else if (type == 2) {
                            analysisImagePath = files[i].getAbsolutePath() + File.separator + "详情";
                            goodsDetailmages = getFileList_ImageItems(analysisImagePath, type);
                        } else {
                            analysisImagePath = thisPath + "竞拍晒单" + File.separator + dirName;
                            evaluateImages = getFileList_ImageItems(analysisImagePath, type);
                        }
                    }
                } else { // 判断文件名是否以.avi结尾
                    String strFileName = files[i].getAbsolutePath();
                    System.out.println("---" + strFileName);
                }
            }
        }
    }

    public List<AnalysisImageVo> getFileList_ImageItems(String strPath, Integer type) {
        List<AnalysisImageVo> analysisImageVos = Lists.newArrayList();
        File dir = new File(strPath);
        File[] files = dir.listFiles(); // 该文件目录下文件全部放入数组
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                String fileName = files[i].getName().replace(" ", "");
                if (!files[i].isDirectory()) { // 判断是文件还是文件夹
                    if (fileName.toLowerCase().contains("xls")) {//调过xls文件读取
                        continue;
                    }
                    AnalysisImageVo analysisImageVo = new AnalysisImageVo();
                    analysisImageVo.setImagePath(files[i].getAbsolutePath().trim());
                    String fileNameWitchOutPrefix = fileName;
                    String prefix = fileNameWitchOutPrefix.substring(fileNameWitchOutPrefix.lastIndexOf("."));
                    int num = prefix.length();
                    analysisImageVo.setName(fileName);
                    if (type != 3) {
                        analysisImageVo.setSort(Integer.valueOf(fileNameWitchOutPrefix.substring(0, fileNameWitchOutPrefix.length() - num)));
                    } else {
                        analysisImageVo.setSort(i);
                    }
                    analysisImageVos.add(analysisImageVo);
                }
            }
        }
        analysisImageVos = Linq4j.asEnumerable(analysisImageVos).orderBy(new Function1<AnalysisImageVo, Comparable>() {
            @Override
            public Comparable apply(AnalysisImageVo cateVo_imageItems) {
                return cateVo_imageItems.getSort();
            }
        }).toList();
        return analysisImageVos;
    }


}
